import React from 'react';
import { Card } from 'antd';
import ItemCell from '../components/cell-item';
import { BillPreviewProps, RowItemProps } from '../props-type';
import { getModeData } from '../common/help';
import { BASE_WIDTH } from '../common/constant';
import '../style/index.less';

/**
 * 组件功能：票据预览区块页面
 *
 */
export default function BillPreview({
    type,
    billJson,
    billImageList,
    cellSelectedId,
    templateData,
    onSelectCell,
}: BillPreviewProps) {
    // console.warn('BillPreview', billJson, templateData);
    /**
     * 这里需要定义预览区的宽度，同时需要定义出基础宽度样式,需要根据提供的票据宽度进行基本的宽度换算
     * 这里，我们也不按80、58、这样的去做区分，我们只认准模板设定的width即可; 我们以不变应万变
     * 当前关系如下：80 -> 48; 58 -> 32;
     * 这里以80的为基准进行计算 也就是80的占100%，即48的占100%；其他的跟48除以计算即可
     */
    // 获取模板内容宽度
    const { width } = billJson;
    const computeWidth = width && typeof Number(width) === 'number' ? Number(width) : 48;
    // 计算预览主容器宽度，向上取整，这里内容区宽度计算后，还得加上padding的值
    const mainContainerWidth = Math.ceil(computeWidth * BASE_WIDTH / 48) + 24 * 2;
    // RowItem渲染
    // 测试调用
    // formatCellValue('１２３，；（全角，占两个字节）function ToSBC(string){', 26, '-', '0', '0');
    // 全局增肌row的key标识
    let indexRowkey = 0;
    let indexRowItemKey = 0;
    // 递归渲染row
    const getRows = (rows, billWidth, block_id, rowData) => {
        indexRowItemKey += 1;
        return rows.map((itemRows, indexRows) => {
            // rowItemProps
            const rowItemProps = {
                billWidth,
                block_id,
                itemRows,
                rowData,
                onSelectCell,
            };
            return <RowItem key={`${block_id}_${indexRowItemKey}_${indexRows}`} {...rowItemProps} />;
        });
    };
    const RowItem = ({
        billWidth,
        block_id,
        itemRows,
        rowData,
    }: RowItemProps): any => {
        indexRowkey += 1;
        const { cell, data, data_list, row_type, row_style, row_child } = itemRows;
        const parentParam = data || data_list;
        // 如果当前row里的dispay不为空，并且里面变量的值不存在(这里需要排除row_type是2跟3，即条形码跟二维码的情况，因为这两种情况后端不能提供渲染数据)，那么返回null
        if ((row_type === '0' || row_type === '1' || row_type === '4') && itemRows.display !== '' && !getModeData(null, null, itemRows.display, rowData, templateData)) return null;
        // 这里根据row_type进行不同的展示：大概分为3中类型，1）字符串、2）列表、3）二维码、图片、条形码，所以考虑用if else语句
        const rowDomRender = [];
        let rowDom = null;
        // 这里判断如果当前row_style第三个字段有大于0的数，那么就渲染具体的空行
        const rowStyleArray = row_style.split(',');
        if (rowStyleArray[2] > 0) {
            for (let i = 0; i < rowStyleArray[2]; i += 1) {
                rowDomRender.push(<p key={i} className="row-white">&nbsp;</p>);
            }
        }
        // 如果row_type为1，获取到具体的列表json，然后进行遍历;如果row_type不为1，那么就正常渲染；这里注意不管父级的row_type如何，下一级的row_type都不受影响
        if (row_type === '1') {
            // 先考虑一级的cell渲染, 这里需要取父级模型data_list的值，正常请下是不出问题的，但是万一取不到，就需要用空数组，防止报错
            const dataList = getModeData(row_type, data_list, null, rowData, templateData) || [];
            // 根据dataList值，循环遍历
            rowDom = dataList.map((rowCellItem) => {
                const rowCellDom = [];
                const rowCellElement = (<div key={`${block_id}_row_${String(indexRowkey)}`} className="row">
                    {/* cell列表开始 */}
                    {cell && Array.isArray(cell) ? cell.map((itemCell, indexCell) => {
                        // cellItemProps
                        const cellItemProps = {
                            type,
                            item: itemCell,
                            itemRows,
                            block_id,
                            cellSelectedId,
                            row_type,
                            parentParam,
                            billWidth,
                            rowData: rowCellItem,
                            billImageList,
                            templateData,
                            onSelectCell,
                        };
                        return <ItemCell key={`${block_id}_row_${String(indexRowkey)}_${indexCell}`} {...cellItemProps} />;
                    }) : ''
                    }
                    {/* cell列表结束 */}
                </div>);
                rowCellDom.push(rowCellElement);
                // 判断如果当前row有row_child，并且row_child的长度大于0，我们就进行递归
                if (row_child && Array.isArray(row_child) && row_child.length > 0) {
                    const childDom = getRows(row_child, billWidth, block_id, rowCellItem);
                    rowCellDom.push(childDom);
                }
                return rowCellDom;
            });
        } else {
            const rowCellDom = [];
            const rowCellElement = (<div key={`${block_id}_row_${String(indexRowkey)}`} className="row">
                {/* cell列表开始 */}
                {cell && Array.isArray(cell) ? cell.map((itemCell, indexCell) => {
                    // cellItemProps
                    const cellItemProps = {
                        type,
                        item: itemCell,
                        itemRows,
                        block_id,
                        cellSelectedId,
                        row_type,
                        parentParam,
                        billWidth,
                        rowData,
                        billImageList,
                        templateData,
                        onSelectCell,
                    };
                    return <ItemCell key={`${block_id}_row_${String(indexRowkey)}_${indexCell}`} {...cellItemProps} />;
                }) : ''
                }
                {/* cell列表结束 */}
            </div>);
            rowCellDom.push(rowCellElement);
            // 判断如果当前row有row_child，并且row_child的长度大于0，我们就进行递归
            if (row_child && Array.isArray(row_child) && row_child.length > 0) {
                const childDom = getRows(row_child, billWidth, block_id, rowData);
                rowCellDom.push(childDom);
            }
            rowDom = rowCellDom;
        }
        rowDomRender.push(rowDom);
        return rowDomRender;
    };
    return (
        <div className={type === 'view' ? 'bill-preview-container bill-templates' : 'bill-preview-container'} style={{ width: mainContainerWidth }}>
            <div className="bill-preview">
                <Card>
                    {/* display进行第一层判断：设计范围block跟row；空是必须显示；变量就根据变量值是否存在 */}
                    {/* row_type做第二层判断：字符串、列表、条形码、二维码、图片 */}
                    {/* font_style第三层判断：有大小、粗细、聚合、对齐、填充 */}
                    {/* 这里需要做必要的判断，防止后端数据错误 */}
                    {billJson && billJson.block && Array.isArray(billJson.block) ? billJson.block.map((itemBlock) => {
                        // 全局需要的参数
                        const billWidth = billJson.width;
                        const { rows, block_id } = itemBlock;
                        // 如果当前block里的dispay不为空，并且里面变量的值不存在，那么返回null
                        if (itemBlock.display !== '' && !getModeData(null, null, itemBlock.display, templateData, templateData)) return null;
                        return (
                            // block开始
                            <div className="block" key={block_id}>
                                {/* 这里不渲染block，根据rows渲染出cell */}
                                {getRows(rows, billWidth, block_id, templateData)}
                            </div>
                            // block结束
                        );
                    }) : ''
                    }
                </Card>
            </div>
        </div>
    );
}